import {
  Injectable,
  Logger,
  BadRequestException,
  NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from '../users/users.entity';
import { VipPackage } from './vip-packages.entity';
import { UserVip } from './user-vip.entity';
import { DiamondTransaction } from './diamond-transaction.entity';
import { PaypalService } from '../paypal/paypal.service';

@Injectable()
export class VipService {
  private readonly logger = new Logger(VipService.name);

  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
    @InjectRepository(VipPackage)
    private vipPackageRepository: Repository<VipPackage>,
    @InjectRepository(UserVip)
    private userVipRepository: Repository<UserVip>,
    @InjectRepository(DiamondTransaction)
    private diamondTransactionRepository: Repository<DiamondTransaction>,
    private readonly paypalService: PaypalService,
  ) {}

  // 获取所有VIP套餐
  async getAllVipPackages(): Promise<VipPackage[]> {
    this.logger.log('获取所有VIP套餐');
    return await this.vipPackageRepository.find({ where: { isActive: true } });
  }

  // 根据ID获取VIP套餐
  async getVipPackageById(id: number): Promise<VipPackage> {
    this.logger.log(`根据ID获取VIP套餐: ${id}`);
    const vipPackage = await this.vipPackageRepository.findOne({
      where: { id, isActive: true },
    });
    if (!vipPackage) {
      throw new NotFoundException('VIP套餐不存在');
    }
    return vipPackage;
  }

  // 使用粉钻购买VIP
  async purchaseVipWithDiamonds(
    userId: number,
    packageId: number,
  ): Promise<any> {
    this.logger.log(`用户${userId}使用粉钻购买VIP套餐${packageId}`);

    const queryRunner =
      this.usersRepository.manager.connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 获取用户信息并加锁防止并发问题
      const user = await queryRunner.manager.findOne(User, {
        where: { id: userId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!user) {
        throw new NotFoundException('用户不存在');
      }

      // 获取VIP套餐信息
      const vipPackage = await queryRunner.manager.findOne(VipPackage, {
        where: { id: packageId, isActive: true },
      });
      if (!vipPackage) {
        throw new NotFoundException('VIP套餐不存在或已停用');
      }

      // 检查用户粉钻余额
      if (user.diamonds < vipPackage.price) {
        throw new BadRequestException(
          `粉钻余额不足。当前余额: ${user.diamonds}，所需: ${vipPackage.price}`,
        );
      }

      // 扣除粉钻
      user.diamonds -= vipPackage.price;

      // 计算VIP到期时间
      const currentTime = new Date();
      let vipEndTime = user.vipEndTime ? new Date(user.vipEndTime) : new Date();

      // 如果VIP已过期，从当前时间开始计算
      if (vipEndTime < currentTime) {
        vipEndTime = new Date();
      }

      vipEndTime.setDate(vipEndTime.getDate() + vipPackage.durationDays);
      user.vipEndTime = vipEndTime;

      // 只有当VIP有效期未过期时，才设置为VIP用户
      user.isVip = vipEndTime > currentTime;

      await queryRunner.manager.save(User, user);

      // 记录交易
      const transaction = new DiamondTransaction();
      transaction.userId = userId;
      transaction.amount = -vipPackage.price;
      transaction.balanceAfter = user.diamonds;
      transaction.transactionType = 'purchase';
      transaction.description = `购买VIP套餐: ${vipPackage.name}`;
      transaction.relatedId = packageId;
      await queryRunner.manager.save(DiamondTransaction, transaction);

      // 更新用户VIP状态
      let userVip = await queryRunner.manager.findOne(UserVip, {
        where: { userId: userId },
      });

      if (!userVip) {
        userVip = new UserVip();
        userVip.userId = userId;
      }

      userVip.packageId = packageId;
      userVip.startTime = new Date();
      userVip.endTime = vipEndTime;
      userVip.isActive = true;
      await queryRunner.manager.save(UserVip, userVip);

      await queryRunner.commitTransaction();

      return {
        success: true,
        message: 'VIP开通成功',
        data: {
          user: {
            diamonds: user.diamonds,
            isVip: user.isVip,
            vipEndTime: user.vipEndTime,
          },
        },
      };
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error(`VIP购买失败: ${error.message}`, error.stack);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  // 获取用户VIP状态
  async getUserVipStatus(userId: number): Promise<any> {
    this.logger.log(`获取用户${userId}的VIP状态`);

    const user = await this.usersRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    const userVip = await this.userVipRepository.findOne({
      where: { userId: userId },
      relations: ['package'],
    });

    // 检查VIP是否过期，如果过期则更新状态
    if (
      user.isVip &&
      user.vipEndTime &&
      new Date(user.vipEndTime) < new Date()
    ) {
      user.isVip = false;
      await this.usersRepository.save(user);
    }

    return {
      isVip: user.isVip,
      vipEndTime: user.vipEndTime,
      userVip: userVip,
    };
  }

  // 充值粉钻（模拟接口，实际应通过支付回调处理）
  async rechargeDiamonds(
    userId: number,
    amount: number,
    diamonds: number,
  ): Promise<any> {
    this.logger.log(
      `用户${userId}充值粉钻，金额：${amount}，粉钻数量：${diamonds}`,
    );

    const queryRunner =
      this.usersRepository.manager.connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 获取用户信息
      const user = await queryRunner.manager.findOne(User, {
        where: { id: userId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!user) {
        throw new NotFoundException('用户不存在');
      }

      // 增加粉钻
      user.diamonds += diamonds;
      await queryRunner.manager.save(User, user);

      // 记录交易
      const transaction = new DiamondTransaction();
      transaction.userId = userId;
      transaction.amount = diamonds;
      transaction.balanceAfter = user.diamonds;
      transaction.transactionType = 'recharge';
      transaction.description = `充值 ${diamonds} 粉钻`;
      await queryRunner.manager.save(DiamondTransaction, transaction);

      await queryRunner.commitTransaction();

      return {
        success: true,
        message: '充值成功',
        data: {
          diamonds: user.diamonds,
        },
      };
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error(`充值失败: ${error.message}`, error.stack);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  // 获取用户粉钻交易记录
  async getUserDiamondTransactions(
    userId: number,
    page: number = 1,
    limit: number = 10,
  ): Promise<any> {
    this.logger.log(
      `获取用户${userId}的粉钻交易记录，页码：${page}，每页数量：${limit}`,
    );

    const [transactions, total] =
      await this.diamondTransactionRepository.findAndCount({
        where: { userId: userId },
        order: { createdAt: 'DESC' },
        skip: (page - 1) * limit,
        take: limit,
      });

    return {
      transactions,
      total,
      page,
      limit,
    };
  }

  // 创建 PayPal 充值订单
  async createPaypalRechargeOrder(
    userId: number,
    amount: number,
    diamonds: number,
  ): Promise<any> {
    this.logger.log(
      `用户${userId}创建PayPal充值订单，金额：${amount}，粉钻数量：${diamonds}`,
    );

    try {
      // 创建 PayPal 订单
      const orderId = await this.paypalService.createOrder(
        amount.toFixed(2),
        'USD',
        `充值 ${diamonds} 粉钻`,
      );

      return {
        success: true,
        data: {
          orderId,
          amount,
          diamonds,
        },
        message: 'PayPal订单创建成功',
      };
    } catch (error: any) {
      this.logger.error(`创建PayPal订单失败: ${error.message}`);
      return {
        success: false,
        message: '创建PayPal订单失败: ' + error.message,
      };
    }
  }

  // 执行 PayPal 充值
  async executePaypalRecharge(userId: number, orderId: string): Promise<any> {
    this.logger.log(`用户${userId}执行PayPal充值，订单ID：${orderId}`);

    const queryRunner =
      this.usersRepository.manager.connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 捕获 PayPal 订单
      const captureResult = await this.paypalService.captureOrder(orderId);

      if (captureResult.status !== 'COMPLETED') {
        throw new Error('PayPal支付未完成');
      }

      // 获取用户信息
      const user = await queryRunner.manager.findOne(User, {
        where: { id: userId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!user) {
        throw new NotFoundException('用户不存在');
      }

      // 从订单中获取金额和粉钻数量
      const purchaseUnit = captureResult.purchase_units[0];
      const amount = parseFloat(purchaseUnit.amount.value);
      // 简单按1:10的比例计算粉钻数量（实际应该从订单信息中获取）
      const diamonds = amount * 10;

      // 增加粉钻
      user.diamonds += diamonds;
      await queryRunner.manager.save(User, user);

      // 记录交易
      const transaction = new DiamondTransaction();
      transaction.userId = userId;
      transaction.amount = diamonds;
      transaction.balanceAfter = user.diamonds;
      transaction.transactionType = 'recharge';
      transaction.description = `PayPal充值 ${amount} USD，获得 ${diamonds} 粉钻`;
      await queryRunner.manager.save(DiamondTransaction, transaction);

      await queryRunner.commitTransaction();

      return {
        success: true,
        message: '充值成功',
        data: {
          diamonds: user.diamonds,
        },
      };
    } catch (error: any) {
      await queryRunner.rollbackTransaction();
      this.logger.error(`PayPal充值失败: ${error.message}`, error.stack);
      return {
        success: false,
        message: '充值失败: ' + error.message,
      };
    } finally {
      await queryRunner.release();
    }
  }
}
